package com.yuyang.wifi.utils.oss;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.OSSLog;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSStsTokenCredentialProvider;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.GetObjectRequest;
import com.alibaba.sdk.android.oss.model.GetObjectResult;
import com.alibaba.sdk.android.oss.model.OSSRequest;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.yuyang.wifi.utils.ToastUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import androidx.annotation.NonNull;

import static android.widget.Toast.LENGTH_SHORT;

public class OssService {

    private OSS mOss;
    private String accessKeyId;
    private String bucketName;
    private String accessKeySecret;
    private String endpoint;
    private Context context;

    private ProgressCallback progressCallback;
    private UploadSuccessListener uploadSuccessListener;

    public OssService(Context context, String accessKeyId, String accessKeySecret, String endpoint, String bucketName) {
        this.context = context;
        this.endpoint = endpoint;
        this.bucketName = bucketName;
        this.accessKeyId = accessKeyId;
        this.accessKeySecret = accessKeySecret;
    }


    public void initOSSClient(Context context, String AccessKeyId, String SecretKeyId, String SecurityToken) {
        OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider(
                AccessKeyId, SecretKeyId, SecurityToken);
        //这个初始化安全性没有Sts安全，如需要很高安全性建议用OSSStsTokenCredentialProvider创建（上一行创建方式）多出的参数SecurityToken为临时授权参数
        // OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(accessKeyId, accessKeySecret);
        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(15 * 1000); // 连接超时，默认15秒
        conf.setSocketTimeout(15 * 1000); // socket超时，默认15秒
        conf.setMaxConcurrentRequest(8); // 最大并发请求数，默认5个
        conf.setMaxErrorRetry(2); // 失败后最大重试次数，默认2次
        // oss为全局变量，endpoint是一个OSS区域地址
        mOss = new OSSClient(context, endpoint, credentialProvider, conf);

    }

    public void uploadFile(final Context context, final String filename, String path, final OnUploadListener listener) {
        try {
            //通过填写文件名形成objectname,通过这个名字指定上传和下载的文件
            String objectname = filename;
            if (objectname == null || objectname.equals("")) {
                ToastUtils.showShortToast(context, "文件名不能为空");
                return;
            }
            //下面3个参数依次为bucket名，Object名，上传文件路径
            PutObjectRequest put = new PutObjectRequest(bucketName, objectname, path);
            if (path == null || path.equals("")) {
                Log.e("oss", "请选择图片....");
                return;
            }
            // 异步上传，可以设置进度回调
            put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
                @Override
                public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                    Log.e("oss", "currentSize: " + currentSize + " totalSize: " + totalSize);
                    double progress = currentSize * 1.0 / totalSize * 100.f;
                }
            });
            @SuppressWarnings("rawtypes")
            OSSAsyncTask task = mOss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
                @Override
                public void onSuccess(PutObjectRequest request, PutObjectResult result) {

                    listener.onUploadSuccess();
                    //根据上传的objectKey去获取下载该上传文件的url
                    //  String uploadOssUrl = mOss.presignPublicObjectURL(bucketName, filename);

                }

                @Override
                public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                    // 请求异常
                    //Log.e("oss", "UploadFailure");

                    listener.onUploadFailed();

                    if (clientExcepion != null) {
                        // 本地异常如网络异常等
                        clientExcepion.printStackTrace();
                    }
                    if (serviceException != null) {
                        // 服务异常
                        Log.e("oss", "UploadFailure：表示在OSS服务端发生错误");
                        Log.e("oss", "ErrorCode" + serviceException.getErrorCode());
                        Log.e("oss", "RequestId" + serviceException.getRequestId());
                        Log.e("oss", "HostId" + serviceException.getHostId());
                        Log.e("oss", "RawMessage" + serviceException.getRawMessage());
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public ProgressCallback getProgressCallback() {
        return progressCallback;
    }

    public void setProgressCallback(ProgressCallback progressCallback) {
        this.progressCallback = progressCallback;
    }

    public interface ProgressCallback {
        void onProgressCallback(double progress);
    }

    //上传成功的回调
    public void setUploadSuccessListener(UploadSuccessListener uploadSuccessListener) {
        this.uploadSuccessListener = uploadSuccessListener;
    }

    public interface UploadSuccessListener {
        void onUploadSuccessCallback();
    }


    public void downloadFile(String objectName, final String bucketName, final String fileName, final OnDownloadListener listener) {
        final long get_start = System.currentTimeMillis();
        OSSLog.logDebug("get start");
        if ((objectName == null) || objectName.equals("")) {
            Log.w("AsyncGetImage", "ObjectNull");
            return;
        }

        OSSLog.logDebug("create GetObjectRequest");
        GetObjectRequest get = new GetObjectRequest(bucketName, objectName);
        get.setCRC64(OSSRequest.CRC64Config.YES);
        get.setProgressListener(new OSSProgressCallback<GetObjectRequest>() {
            @Override
            public void onProgress(GetObjectRequest request, long currentSize, long totalSize) {
                OSSLog.logDebug("getobj_progress: " + currentSize + "  total_size: " + totalSize, false);
                Log.d("GetObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
                int progress = (int) (100 * currentSize / totalSize);

                // listener.onDownloading(progress);
            }
        });

        OSSLog.logDebug("asyncGetObject");
        OSSAsyncTask task = mOss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
            @Override
            public void onSuccess(GetObjectRequest request, GetObjectResult result) {
                // 请求成功
                Log.e("zzz", "HelloMoonFragment--onSuccess--");
                // 请求成功
                InputStream inputStream = null;
                // byte[] buf = new byte[2048];
                byte[] buf = new byte[1 * 1024 * 1024];
                int len = 0;
                FileOutputStream fos = null;
                try {
                    inputStream = result.getObjectContent();
                    String download = isExistDir("/yuyang/download");
                    File saveFile = new File(download, fileName);
                    fos = new FileOutputStream(saveFile);
                    long sum = 0;
                    while ((len = inputStream.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        // int progress = (int) (sum * 1.0f / total * 100);
                        // 下载中
                        //listener.onDownloading(progress);
                    }
                    fos.flush();
                    //下载完成
                    listener.onDownloadSuccess();
                } catch (IOException e) {
                    e.printStackTrace();
                    //下载失败
                    listener.onDownloadFailed();
                } finally {
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fos != null) {
                        try {
                            fos.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

            @Override
            public void onFailure(GetObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                listener.onDownloadFailed();
                String info = "";
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                    info = clientExcepion.toString();
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                    info = serviceException.toString();
                }
            }
        });
    }

    public void saveBitmap(Bitmap bitmap) {
        // 首先保存图片
        File appDir = new File(Environment.getExternalStorageDirectory(), "zxing_image");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = "zxing_image" + ".png";
        File file = new File(appDir, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 把文件插入到系统图库
        try {
            MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName, null);
        } catch (FileNotFoundException e) {
            Toast.makeText(context, "图片保存失败", LENGTH_SHORT).show();
            e.printStackTrace();
        }
        // 通知图库更新
        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + "/sdcard/namecard/")));

    }

    /**
     * @param url
     * @return 从下载连接中解析出文件名
     */
    @NonNull
    private String getNameFromUrl(String url) {
        return url.substring(url.lastIndexOf("/") + 1);
    }

    public interface OnDownloadListener {
        /**
         * 下载成功
         */
        void onDownloadSuccess();

        /**
         * @param progress 下载进度
         */
        void onDownloading(int progress);

        /**
         * 下载失败
         */
        void onDownloadFailed();
    }


    public interface OnUploadListener {
        /**
         * 上传成功
         */
        void onUploadSuccess();

        /**
         * @param progress 上传进度
         */
        void onUploading(double progress);

        /**
         * 上传失败
         */
        void onUploadFailed();

    }


    /**
     * @param saveDir
     * @return
     * @throws IOException 判断下载目录是否存在
     */
    private String isExistDir(String saveDir) throws IOException {
        // 下载位置
        File downloadFile = new File(Environment.getExternalStorageDirectory(), saveDir);
        if (!downloadFile.mkdirs()) {
            downloadFile.createNewFile();
        }
        String savePath = downloadFile.getAbsolutePath();
        return savePath;
    }

}
